//
// Created by moon on 2023/9/19.
//

#ifndef _STM32YMODEM_H
#define _STM32YMODEM_H

#include "ymodem/ymodem.h"
#include <string.h>

#define FLASH_WRITE_START_ADDRESS 0x8010000


class Stm32Update : public YModem {
#define UPDATE_FLAG     0x55AAA55A

public:
    enum {
        APP0 = 0,
        APP1 = 1
    };

    struct UpdateInfo_t {
        uint32_t flag;
        uint16_t update;
        uint16_t last_app;      //上次更新地址
        uint32_t app_addr[2];
        uint32_t update_count;  //更新次数
    };

    struct FlashUpdateInfo_t {
        struct UpdateInfo_t    info;
        YModem::FileProperty_t file0;
        YModem::FileProperty_t file1;
    };

public:
    explicit Stm32Update(uint32_t info_addr, uint32_t firmware_max_size) :
            update_info_addr(info_addr), update_max_size(firmware_max_size) {

        write_addr = 0;
        read_addr  = 0;
    }

    ~Stm32Update() = default;

    int init(uint32_t app0_addr, uint32_t app1_addr);

    void successful();
    void fail();

    void gotoApp();

public:
    YModem::FileProperty_t *fileGetProperty() override { return file; }

    void fileSetProperty(FileProperty_t *property) override;

protected:
    uint32_t write(uint8_t *data, uint32_t len) override;
    uint32_t read(uint8_t *data, uint32_t len) override;

    //弃用
    int fileOperate(FileOperateType type, uint8_t *data, uint32_t len);

    int fileOpen(FileOperateType type) override;
    int fileClose() override;
    uint32_t fileWrite(uint8_t *data, uint32_t size) override;
    uint32_t fileRead(uint8_t *data, uint32_t size) override;

private:
    uint32_t update_info_addr;
    uint32_t update_addr;
    uint32_t update_max_size;

    uint32_t write_addr;
    uint32_t read_addr;

    FlashUpdateInfo_t      firmware_data;
    UpdateInfo_t           *updateInfo; //  指向 FlashUpdateInfo_t 中的 UpdateInfo_t
    YModem::FileProperty_t *file;   //  指向 FlashUpdateInfo_t 中的 FileProperty_t

};


#endif //_STM32YMODEM_H
